﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FACUI.BasicClass
{
    public class CRC32
    {
        public CRC32()
        {
            //getCRCTables();
        }
        private uint[] CRCtable = new uint[]{
                    0x00000000, 0x04C10CB7, 0x0982196E, 0x0D4315D9, 0x130432DC, 0x17C53E6B, 0x1A862BB2, 0x1E472705, 
                    0x260865B8, 0x22C9690F, 0x2F8A7CD6, 0x2B4B7061, 0x350C5764, 0x31CD5BD3, 0x3C8E4E0A, 0x384F42BD, 
                    0x4C10CB70, 0x48D1C7C7, 0x4592D21E, 0x4153DEA9, 0x5F14F9AC, 0x5BD5F51B, 0x5696E0C2, 0x5257EC75, 
                    0x6A18AEC8, 0x6ED9A27F, 0x639AB7A6, 0x675BBB11, 0x791C9C14, 0x7DDD90A3, 0x709E857A, 0x745F89CD, 
                    0x982196E0, 0x9CE09A57, 0x91A38F8E, 0x95628339, 0x8B25A43C, 0x8FE4A88B, 0x82A7BD52, 0x8666B1E5, 
                    0xBE29F358, 0xBAE8FFEF, 0xB7ABEA36, 0xB36AE681, 0xAD2DC184, 0xA9ECCD33, 0xA4AFD8EA, 0xA06ED45D, 
                    0xD4315D90, 0xD0F05127, 0xDDB344FE, 0xD9724849, 0xC7356F4C, 0xC3F463FB, 0xCEB77622, 0xCA767A95, 
                    0xF2393828, 0xF6F8349F, 0xFBBB2146, 0xFF7A2DF1, 0xE13D0AF4, 0xE5FC0643, 0xE8BF139A, 0xEC7E1F2D, 
                    0x34822077, 0x30432CC0, 0x3D003919, 0x39C135AE, 0x278612AB, 0x23471E1C, 0x2E040BC5, 0x2AC50772, 
                    0x128A45CF, 0x164B4978, 0x1B085CA1, 0x1FC95016, 0x018E7713, 0x054F7BA4, 0x080C6E7D, 0x0CCD62CA, 
                    0x7892EB07, 0x7C53E7B0, 0x7110F269, 0x75D1FEDE, 0x6B96D9DB, 0x6F57D56C, 0x6214C0B5, 0x66D5CC02, 
                    0x5E9A8EBF, 0x5A5B8208, 0x571897D1, 0x53D99B66, 0x4D9EBC63, 0x495FB0D4, 0x441CA50D, 0x40DDA9BA, 
                    0xACA3B697, 0xA862BA20, 0xA521AFF9, 0xA1E0A34E, 0xBFA7844B, 0xBB6688FC, 0xB6259D25, 0xB2E49192, 
                    0x8AABD32F, 0x8E6ADF98, 0x8329CA41, 0x87E8C6F6, 0x99AFE1F3, 0x9D6EED44, 0x902DF89D, 0x94ECF42A, 
                    0xE0B37DE7, 0xE4727150, 0xE9316489, 0xEDF0683E, 0xF3B74F3B, 0xF776438C, 0xFA355655, 0xFEF45AE2, 
                    0xC6BB185F, 0xC27A14E8, 0xCF390131, 0xCBF80D86, 0xD5BF2A83, 0xD17E2634, 0xDC3D33ED, 0xD8FC3F5A, 
                    0x690440EE, 0x6DC54C59, 0x60865980, 0x64475537, 0x7A007232, 0x7EC17E85, 0x73826B5C, 0x774367EB, 
                    0x4F0C2556, 0x4BCD29E1, 0x468E3C38, 0x424F308F, 0x5C08178A, 0x58C91B3D, 0x558A0EE4, 0x514B0253, 
                    0x25148B9E, 0x21D58729, 0x2C9692F0, 0x28579E47, 0x3610B942, 0x32D1B5F5, 0x3F92A02C, 0x3B53AC9B, 
                    0x031CEE26, 0x07DDE291, 0x0A9EF748, 0x0E5FFBFF, 0x1018DCFA, 0x14D9D04D, 0x199AC594, 0x1D5BC923, 
                    0xF125D60E, 0xF5E4DAB9, 0xF8A7CF60, 0xFC66C3D7, 0xE221E4D2, 0xE6E0E865, 0xEBA3FDBC, 0xEF62F10B, 
                    0xD72DB3B6, 0xD3ECBF01, 0xDEAFAAD8, 0xDA6EA66F, 0xC429816A, 0xC0E88DDD, 0xCDAB9804, 0xC96A94B3, 
                    0xBD351D7E, 0xB9F411C9, 0xB4B70410, 0xB07608A7, 0xAE312FA2, 0xAAF02315, 0xA7B336CC, 0xA3723A7B, 
                    0x9B3D78C6, 0x9FFC7471, 0x92BF61A8, 0x967E6D1F, 0x88394A1A, 0x8CF846AD, 0x81BB5374, 0x857A5FC3, 
                    0x5D866099, 0x59476C2E, 0x540479F7, 0x50C57540, 0x4E825245, 0x4A435EF2, 0x47004B2B, 0x43C1479C, 
                    0x7B8E0521, 0x7F4F0996, 0x720C1C4F, 0x76CD10F8, 0x688A37FD, 0x6C4B3B4A, 0x61082E93, 0x65C92224, 
                    0x1196ABE9, 0x1557A75E, 0x1814B287, 0x1CD5BE30, 0x02929935, 0x06539582, 0x0B10805B, 0x0FD18CEC, 
                    0x379ECE51, 0x335FC2E6, 0x3E1CD73F, 0x3ADDDB88, 0x249AFC8D, 0x205BF03A, 0x2D18E5E3, 0x29D9E954, 
                    0xC5A7F679, 0xC166FACE, 0xCC25EF17, 0xC8E4E3A0, 0xD6A3C4A5, 0xD262C812, 0xDF21DDCB, 0xDBE0D17C, 
                    0xE3AF93C1, 0xE76E9F76, 0xEA2D8AAF, 0xEEEC8618, 0xF0ABA11D, 0xF46AADAA, 0xF929B873, 0xFDE8B4C4, 
                    0x89B73D09, 0x8D7631BE, 0x80352467, 0x84F428D0, 0x9AB30FD5, 0x9E720362, 0x933116BB, 0x97F01A0C, 
                    0xAFBF58B1, 0xAB7E5406, 0xA63D41DF, 0xA2FC4D68, 0xBCBB6A6D, 0xB87A66DA, 0xB5397303, 0xB1F87FB4};
        private void getCRCTables()
        {
            for (int i = 0; i < 256; ++i)
            {
                uint _crc = (uint)i;
                for (int j = 0; j < 8; ++j)
                {
                    System.Diagnostics.Debug.WriteLine(string.Format("{0}", (_crc ^ (i << (24 + j))) & 0x80000000));
                    if (((_crc ^ (i << (24 + j))) & 0x80000000) == 1)
                        _crc = (_crc << 1) ^ 0x04C10DB7;
                    else
                        _crc <<= 1;
                }
                CRCtable[i] = (uint)_crc;
            }
        }
        public uint getCRC32(byte[] bytes)
        {
            uint curSeed = 0;
            foreach (byte b in bytes)
            {
                curSeed = (curSeed << 8) ^ CRCtable[(curSeed >> 24) ^ b];
            }
            return curSeed;
        }
    }
}
